home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Very Best of Atari Inside
/
The Very Best of Atari Inside 1.iso
/
mint
/
mntlib43
/
mntlib
/
sozobon
/
ps.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-15
|
6KB
|
219 lines
/*
* ps.c - a program to print MiNT process statuses
*
* Based on the original ps by Tony Reynolds, cctony@sgisci1.ocis.olemiss.edu,
* and updated by Eric Smith and Allan Pratt.
* For use with MiNT release 0.9.
* Compiles with my port of the MiNTlib to Sozobon 2.0, as well as the GCC.
*
* $Log: ps.c,v $
* Revision 0.9 1992/01/15 21:48:22 sozobon
* dpg's first version.
* Uses opendir rather than Fsfirst/next.
* Print owner information, rather than parent process id.
*
*/
static char *proc =
"$Id: ps.c,v 0.9 1992/01/15 21:48:22 sozobon Exp sozobon $";
#include <basepage.h>
#include <dirent.h>
#include <errno.h>
#include <ioctl.h>
#include <pwd.h>
#include <stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define PROCDIR "u:/proc"
#define ulong unsigned long
#define ushort unsigned short
extern int __mint;
/* The following structures are taken from proc.h in the MiNT kernel. */
/* a process context consists, for now, of its registers */
typedef struct _context {
long regs[15]; /* registers d0-d7, a0-a6 */
long usp; /* user stack pointer (a7) */
short sr; /* status register */
long pc; /* program counter */
long ssp; /* supervisor stack pointer */
long term_vec; /* GEMDOS terminate vector (0x102) */
char fstate[216]; /* FPU internal state */
char fregs[12*8]; /* registers fp0-fp7 */
long fctrl[3]; /* FPCR/FPSR/FPIAR */
short sfmt; /* stack frame format identifier */
long iar; /* instruction address */
short internal[4]; /* four words of internal info */
} CONTEXT;
#define PROC_CTXTS 2
typedef struct proc {
/* this is stuff that the public can know about */
/* NOTE: some assembly code (in intr.s and contxt.s) makes
* assumptions about the offsets of sysstack, ctxt[0], systime,
* and usrtime.
*/
long sysstack; /* must be first */
CONTEXT ctxt[PROC_CTXTS]; /* must be second */
long magic; /* validation for proc struct */
char *base; /* process base page */
short pid, ppid, pgrp;
short ruid; /* process real user id */
short rgid; /* process real group id */
short euid, egid; /* effective user and group ids */
ushort memflags; /* e.g. malloc from alternate ram */
short pri; /* base process priority */
short wait_q; /* current process queue */
long wait_cond; /* condition we're waiting on */
/* (also return code from wait) */
/* (all times are in milliseconds) */
ulong systime; /* time spent in kernel */
ulong usrtime; /* time spent out of kernel */
ulong chldstime; /* children's kernel time */
ulong chldutime; /* children's user time */
ulong maxmem; /* max. amount of memory to use */
ulong maxdata; /* max. data region for process */
ulong maxcore; /* max. core memory for process */
ulong maxcpu; /* max. cpu time to use */
short domain; /* process domain (TOS or UNIX) */
short curpri; /* current process priority */
#define MIN_NICE -20
#define MAX_NICE 20
} PROC;
/* different process queues */
#define CURPROC_Q 0
#define READY_Q 1
#define WAIT_Q 2
#define IO_Q 3
#define ZOMBIE_Q 4
#define TSR_Q 5
#define STOP_Q 6
#define SELECT_Q 7
#define NUM_QUEUES 8
struct status {
char mint;
char desc;
} proc_stat[NUM_QUEUES + 1] = {
CURPROC_Q, 'R',
READY_Q, 'R',
WAIT_Q, 'S',
IO_Q, 'S',
SELECT_Q, 'S',
STOP_Q, 'T',
ZOMBIE_Q, 'Z',
TSR_Q, 'X',
-1, '?'
}; /* initialized from data in procfs.c */
void
main(argc, argv)
int argc;
char **argv;
{
DIR *dirp;
struct dirent *ent;
struct stat info;
int fd;
int fserror;
long place;
short pid,
ppid,
pri,
curpri;
char *s,
username[9];
struct status *statp;
BASEPAGE bpage; /* process basepage read in here if possible */
PROC proc; /* process info read in here */
long ptime;
long hour,
min,
sec,
frac;
struct passwd *pwent;
if (chdir(PROCDIR) || !(dirp = opendir("."))) {
perror(PROCDIR);
return 1;
}
printf("USER PID PRI/CUR STAT SIZE TIME COMMAND\n");
username[8] = '\0';
while (ent = readdir(dirp)) {
if ((fd = open(ent->d_name, 0)) < 0 || fstat(fd, &info))
goto next;
/* Should really copy the name elsewhere. */
for (s = ent->d_name; *s && *s != '.'; s++);
*s = '\0';
ioctl(fd, PPROCADDR, &place);
lseek(fd, place, 0);
read(fd, &proc, sizeof(proc));
if (pwent = getpwuid(proc.ruid))
strncpy(username, pwent->pw_name, 8);
else
strcpy(username, "??user??");
ptime = proc.systime + proc.usrtime;
hour = (ptime / 1000 / 60 / 60);
min = (ptime / 1000 / 60) % 60;
sec = (ptime / 1000) % 60;
frac = (ptime % 1000) / 10; /* (never anything in .00x digit) */
ioctl(fd, PBASEADDR, &place);
lseek(fd, place, 0);
read(fd, &bpage, sizeof(bpage));
if (*bpage.p_cmdlin)
*bpage.p_cmdlin = ' ';
close(fd);
statp = proc_stat; /* hunt down string referring to process
* status */
while (statp->mint != proc.wait_q &&
statp->mint >= 0)
statp++;
printf("%-8s %03d %3d/%3d %c %c ", username, proc.pid,
proc.pri, proc.curpri, statp->desc,
proc.pri < 0 ? 'N' : proc.pri > 0 ? '<' : ' ');
if (info.st_size > 1000000L)
printf("%3ldM ", info.st_size / 1000000L);
else if (info.st_size > 1000L)
printf("%3ldk ", info.st_size / 1000L);
else
printf("%3ld ", info.st_size);
if (hour)
printf("%02ld:%02ld:%02ld", hour, min, sec);
else
printf("%02ld:%02ld.%02ld", min, sec, frac);
printf(" %s%s\n", ent->d_name, bpage.p_cmdlin);
next:
}
closedir(dirp);
endpwent();
return 0;
}